# !/usr/bin/env python
# -*- coding:utf-8 -*-
'''输出窗口

历史:
    2018-10-24 姚彧 创建
    2018-10-26 控制台输出重定向
    2018-12-05 字符串长度较长时, 进行截断处理
'''

__all__ = ['paneOutput']

import sys
from PyQt5.QtWidgets import QTextEdit, QDockWidget
from PyQt5.QtCore import Qt
from events.EventCenter import (EventContext, EventDispatcher)
from tool.Singleton import Singleton


class paneOutput(QDockWidget, Singleton):
    def __init__(self):
        super().__init__('输出')
        self.__init_ui()
        self.__redirection()

    def emit(self, *args, **kwargs):
        return EventDispatcher().emit(*args, **kwargs)

    def __init_ui(self):
        self.edtOutput = QTextEdit()
        self.setFeatures(QDockWidget.DockWidgetFloatable)
        self.setAllowedAreas(Qt.BottomDockWidgetArea)
        self.setWidget(self.edtOutput)

        self.log('\n'.join(sys.path))
        context = EventContext()
        self.emit('App.Environ.GetAll', context)
        self.log('{app_name} Ver {full_version}'.format(**context['value']))

        context = EventContext(pane_args = (Qt.BottomDockWidgetArea, self))
        self.emit('UI.Dock.Add', context)

    def on_event_print(self, context:EventContext, *args, **kwargs):
        assert context.path == 'on_print'
        self.log(context.get('context', ''))

    def log(self, text):
        old_text = self.edtOutput.toPlainText()
        if len(text) + len(old_text) > 65535:
            text = text[:35000] + ' [omitting some output]'
        else:
            text = '%s\n%s' % (text, self.edtOutput.toPlainText())
        self.edtOutput.setText(text)

    # ###########################################################################
    #  重定向
    def __redirection(self):
        self.__console__ = sys.stdout
        sys.stdout = self

    def flush(self):
        pass

    def write(self, output_stream):
        if output_stream != '\n':
            self.log(output_stream)
        self.__console__.write(output_stream)

    def __del__(self):
        sys.stdout = self.__console__
    #  重定向
    # ###########################################################################

    @classmethod
    def register_events(cls):
        EventDispatcher().register('on_print', cls.getInstance().on_event_print)
